package validator;

import exception.ParamCheckFailureException;
import utils.StringUtils;

/**
 * 校验器，抽象层实现，对接口所有的方法都做一个实现（即使抽象层无法实现的抛出异常，这样不向下传递，方便子类选择性实现）。
 *
 * @Author 小白龙
 * @Date 2021-01-05
 * @Version 1.0
 */
public abstract class AbstractValidator<T, V> implements IValidate<T> {

    public static final String ERROR_MESSAGE_NOT_NULL = "不能为空";
    public static final String ERROR_MESSAGE_LENGTH_NOT_MIN = "长度不能小于";
    public static final String ERROR_MESSAGE_LENGTH_NOT_MAX = "长度不能大于";

    /**
     * 获取参数名称，校验不通过，报错时使用
     *
     * @return
     */
    protected abstract String getParamName();

    /**
     * 获取参数值，通用的校验在这层实现时使用
     *
     * @return
     */
    protected abstract V getParamValue();

    @Override
    public T notNull(String errorMessage) throws ParamCheckFailureException {
        notNull(getParamValue(), errorMessage);
        return (T)this;
    }

    @Override
    public final T notNull() throws ParamCheckFailureException {
        return notNull(getParamName() + ERROR_MESSAGE_NOT_NULL);
    }

    @Override
    public final T min(int min) throws ParamCheckFailureException {
        return min(min, getParamName() + ERROR_MESSAGE_LENGTH_NOT_MIN + min);
    }

    @Override
    public T min(int min, String errorMessage) throws ParamCheckFailureException {
        throw createUnSupportException();
    }

    @Override
    public T max(int max, String errorMessage) throws ParamCheckFailureException {
        throw createUnSupportException();
    }

    @Override
    public final T max(int max) throws ParamCheckFailureException {
        return max(max, getParamName() + ERROR_MESSAGE_LENGTH_NOT_MAX + max);
    }

    @Override
    public final T length(int min, int max, String errorMessage) throws ParamCheckFailureException {
        try {
            this.min(min, null);
            this.max(max, null);
        } catch (ParamCheckFailureException pcf) {
            throw new ParamCheckFailureException(errorMessage);
        }
        return (T)this;
    }

    @Override
    public final T length(int min, int max) throws ParamCheckFailureException {
        String errorMessage = String.format("%s长度不能小于%d,不能大于%d", getParamName(), min, max);
        return length(min, max, errorMessage);
    }

    // ------------------------------------------------------------------------------------- 通用工具方法 start

    /**
     * 创建参数校验不通过异常
     *
     * @param errorMessage
     * @return
     */
    protected static final ParamCheckFailureException createPcfException(String errorMessage) {
        return new ParamCheckFailureException(errorMessage);
    }

    /**
     * 创建不支持的方法异常
     *
     * @return
     */
    protected static final UnsupportedOperationException createUnSupportException() {
        return new UnsupportedOperationException("此方法不支持");
    }


    /**
     * 校验不能为空
     *
     * @param paramValue
     * @param errorMessage
     * @throws ParamCheckFailureException
     */
    protected static final void notNull(Object paramValue, String errorMessage) throws ParamCheckFailureException {
        if (StringUtils.isEmpty(paramValue)) {
            throw createPcfException(errorMessage);
        }
    }

    /**
     * 串联String字符串
     *
     * @param str
     * @return
     */
    protected static final String strConcat(String... str) {
        return StringUtils.buildStr(str, "");
    }

    // ------------------------------------------------------------------------------------- 通用工具方法 end
}
